package com.adcc.monitoragent.core.service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import com.adcc.monitoragent.bean.RedisBean;
import com.adcc.monitoragent.log.ServiceLogger;
import com.adcc.monitoragent.send.MessageSend;
import com.adcc.monitoragent.util.Constants;
import com.adcc.monitoragent.util.ProtertiesUtil;

/**
 * ip + port 唯一确定
 * 内存数据库监控
 * 
 * @author charlie
 * 
 */
@PersistJobDataAfterExecution   
@DisallowConcurrentExecution
public class RedisService implements Job {
	private final static Logger log = LoggerFactory.getLogger(RedisService.class);
	/**
	 * redis连接池
	 */
	private static Map<String, JedisPool> jedisPool = new ConcurrentHashMap<String, JedisPool>();
	private static Map<String, RedisBean> lastRedisBeanMap = new ConcurrentHashMap<String, RedisBean>();

	/**
	 * 获取redis连接池
	 * @param ip
	 * @param port
	 * @return
	 */
	private static JedisPool getPool(String ip, int port, String username, String password) 
    { 
		String key = ip + ":" + port;
		JedisPool pool = jedisPool.get(key);
		if(pool == null) {
			try {
				// 池基本配置 
				JedisPoolConfig config = new JedisPoolConfig(); 
				config.setMaxActive(20); 
				config.setMaxIdle(5); 
				config.setMaxWait(1000l); 
				config.setTestOnBorrow(false); 
				//默认是2秒超时，时间长一点，防止监控失效
				pool = new JedisPool(config, ip, port, 6000);
				jedisPool.put(key, pool);
			} catch (Exception e) {
				if(pool != null) {
					pool.destroy();
				}
				return null;
			} 
		}
        return pool;
    } 
	
	public static RedisBean getInfo(String ip, int port, String username, String password) {
		RedisBean redisBean = new RedisBean();
		redisBean.setIp(ip);
		redisBean.setPort(port + "");
		JedisPool pool = getPool(ip, port, username, password);
		Jedis client = null;
		try {
			client = pool.getResource();
			
			redisBean.setStatus(Constants.STATUS_OK);
			// 执行操作
			client.set("test", "test");
			client.get("test");
			client.del("test");
			redisBean.setDb(String.valueOf(client.getDB().intValue() + 1));
			redisBean.setDbSize(client.dbSize().toString());
			redisBean.setKeySize(String.valueOf(client.dbSize()));
			redisBean.setSaveTime(String.valueOf(Long.parseLong(client
					.lastsave()
					+ "000")));
		} catch (Exception e) {
			log.error("连接redis失败" + e.getMessage());
			redisBean.setStatus(Constants.STATUS_ERROR);
			if(client != null) {
				pool.returnBrokenResource(client); 
				client = null;
			}
			
		} finally {
			if(client != null) {
				pool.returnResource(client); 
				client = null;
			}
		}
		
		return redisBean;
	}
	
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		log.debug("定时执行任务。。。。。。。。。。。。");
		for (Object objStr : ProtertiesUtil.getRedisConnectString()) {
			try {
				String[] s = objStr.toString().split(":");
				RedisBean redisBean = RedisService.getInfo(s[0], Integer.parseInt(s[1]),
						ProtertiesUtil.getRedisUsername(), ProtertiesUtil.getRedisPassword());
				String key = redisBean.buildKey();
				RedisBean lastRedisBean = lastRedisBeanMap.get(key);
				boolean statusChange = lastRedisBean != null && !lastRedisBean.getStatus().equals(redisBean.getStatus());
				if(redisBean.getStatus().equals(Constants.STATUS_ERROR) && statusChange) {//如果状态异常 并且 状态改变
					log.warn("Redis状态正常转异常，休眠2秒重试，防止误判");
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
					}
					redisBean = RedisService.getInfo(s[0], Integer.parseInt(s[1]),
							ProtertiesUtil.getRedisUsername(), ProtertiesUtil.getRedisPassword());
					if(redisBean.getStatus().equals(Constants.STATUS_ERROR)) {//状态还是异常
						String desc = "服务停止";
						ServiceLogger.error(redisBean.getIp(), redisBean.getPort(), "redis", desc);
					}
				} else if(statusChange){//状态由异常转正常
					String desc = "服务启动";
					ServiceLogger.info(redisBean.getIp(), redisBean.getPort(), "redis", desc);
				}
				lastRedisBeanMap.put(key, redisBean);
				//转发消息
				MessageSend.sendMsg(redisBean);
			} catch (Exception e) {
				log.error("Redis定时任务执行失败:" + objStr +  e.getMessage());
			}
		}
		log.debug("完成任务。。。。。。。。。。。。");
	}
	
	public static void main(String[] args) throws Exception {
		RedisBean redisBean = RedisService.getInfo("192.168.0.90", 6379, null, null);
		System.out.println(redisBean.toString());
	}
}
